<?php
namespace base;

use ReflectionClass;
use base\tools\FileLock;
use think\facade\Event;
use base\ServiceContainer;


class BaseService
{
	//时间分隔标识
	protected $btflag=' - ';

	protected $lockObj = null;

	/**
	 * 服务容器
	 * @var ServiceContainer
	 */
	public $container;
	

	/**
	 * 根据配置生成链式查询
	 *
	 * @param object $obj
	 * @param array $param
	 * @param array $config
	 * @param mixed $scene
	 * @param string $field
	 * @param array $with
	 * @return object
	 */
	protected function buildwhere($obj,$param,$config=[]){

		if(empty($param)||empty($config)){
			return $obj;
		}
		if(empty($config['where'])){
			$whereConfig = $config;
		}else{
			$whereConfig = $config['where'];
		}

		foreach($whereConfig as $k=>$v){
			if(!isset($param[$k])||(empty($param[$k])&&$param[$k]!==0&&$param[$k]!=='0'))  continue;
			
			switch ($v[1]) {
				case 'like':
					$obj=$obj->whereLike($v[0],'%'.$param[$k].'%');
					break;

				case 'time':
				
					list($start,$end)=explode($this->btflag,$param[$k]);
					

					$obj=$obj->whereBetweenTime($v[0],$start,$end);

					break;
				
				default:

					$obj=$obj->where($v[0],$v[1],$param[$k]);
					break;
			}

			if(!empty($v[2])&&$v[2]==1){
				return $obj;
			}
		}

		if(!empty($config['query_scene'])){
			$sceneConfig = $config['query_scene'];
			$obj = $this->buildField($obj,$param['query_scene']??null,$sceneConfig,$param['field']??'',$param['with']??[]);
		}

		if(!empty($config['order'])){
			$order = $config['order'][$param['order']??'default'];
			$obj->order($order);
		}

		if(!empty($param['test'])){
			$obj=$obj->fetchSql();
		}

		return $obj;
	}

	/**
	 * 根据场景构建字段和关联关系
	 *
	 * @param object $obj
	 * @param string $scene
	 * @param array $config
	 * @param string $field
	 * @param array $with
	 * @return object
	 */
	protected function buildField($obj,$scene,$config,$field='',$with=[],$join=[])
	{
		if($scene==null)return $obj;

		if($scene=='cus'){
			$field = $field;
			$with = $with;
			$join = $join;
		}else{
			$config = $config[$scene]??null;
			if(!$config)return $obj;
			$field = $config['field'];
			$with = $config['with']??[];
			$join = $config['join']??[];
			$hidden = $config['hidden']??[];
		}

		return $obj->field($field)->with($with)->hidden($hidden)->withJoin($join);
	}

	/**
	 * 事件触发器
	 *
	 * @param string $name
	 * @param array $param
	 * @return void
	 */
	protected function trigger($name,$param)
	{
		return Event::trigger($name,$param);
	}

	/**
	 * 前置逻辑处理
	 *
	 * @param mixed ...$param 可变参数列表
	 * @return void
	 */
	protected function before(&...$param)
	{
		return $this->container->execLogic('before',...$param);
	}

	/**
	 * 后置逻辑处理
	 *
	 * @param mixed ...$param 可变参数列表
	 * @return void
	 */
	protected function after(&...$param)
	{
		return $this->container->execLogic('after',...$param);
	}

	/**
	 * 服务错误信息
	 *
	 * @param string $info
	 * @return void
	 */
	public function error(string $info)
	{
		$this->container->context->errInfo = $info;
		return false;
	}

	/**
	 * 加锁
	 *
	 * @param [type] $name
	 * @param string $path
	 * @return void
	 */
	protected function lock($name,$path='')
	{
		$this->lockObj = new FileLock($name,$path);

		return $this->lockObj->lock();
	}

	/**
	 * 解锁
	 *
	 * @return void
	 */
	protected function unLock()
	{
		$this->lockObj->unlock();
	}


}